/*
 * by wlh 
 * date 2025/09/23 15:46
 */
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEditor.Experimental.GraphView;
using UnityEngine;

public static class GraphToMermaid
{

    // %% PosDef:begin
    // %%  C:pos:500,100
    // %%  F:pos:100,400
    // %% PosDef:end
    public static string ConvertToMermaid(GraphView graphView, string title = "Graph")
    {
        StringBuilder mermaidBuilder = new ();
        StringBuilder commentBuilder = new ();
        commentBuilder.AppendLine("%% PosDef:begin");

        // 添加 Mermaid 标题和方向
        mermaidBuilder.AppendLine($"%% {title}");
        mermaidBuilder.AppendLine("graph LR");
        mermaidBuilder.AppendLine();

        // 获取所有节点和边
        var nodes = graphView.nodes.ToList().Cast<Node>().ToList();
        var edges = graphView.edges.ToList();

        // 处理节点
        mermaidBuilder.AppendLine("%% 节点定义");
        foreach (Node node in nodes)
        {
            var mermaidNode = node.userData as MermaidNode;
            string nodeId = mermaidNode.mermaidId; //GetNodeId(node);
            string nodeLabel = mermaidNode.Text; // GetNodeLabel(node);
            string nodeShape = dicShape[mermaidNode.shape]; //GetNodeShape(node);
            Vector2 position = GetNodePosition(node);

            // 节点定义单独一行
            mermaidBuilder.AppendLine($"    {nodeId}{nodeShape}{nodeLabel}{GetShapeClosing(nodeShape)}");
            // 位置注释单独一行
            commentBuilder.AppendLine($"    %%  {nodeId}:pos:{position.x:F0},{position.y:F0}");
        }
        commentBuilder.AppendLine("%% PosDef:end");
        mermaidBuilder.AppendLine();

        // 处理边
        mermaidBuilder.AppendLine("%% 边连接");
        foreach (Edge edge in edges)
        {
            if (edge.output?.node is Node outputNode && edge.input?.node is Node inputNode)
            {
                var mermaidNode = outputNode.userData as MermaidNode;
                string outputId = mermaidNode.mermaidId; //GetNodeId(outputNode);
                mermaidNode = inputNode.userData as MermaidNode;
                string inputId = mermaidNode.mermaidId; // GetNodeId(inputNode);

                // 添加边连接
                mermaidBuilder.AppendLine($"    {outputId} --> {inputId}");
            }
        }

        mermaidBuilder.AppendLine();
        mermaidBuilder.Append(commentBuilder);

        return mermaidBuilder.ToString();
    }

    // 根据节点样式确定Mermaid形状
    static Dictionary<MermaidParser.NodeShape, string> dicShape = new() 
    { 
        { MermaidParser.NodeShape.Rect, "["},
        { MermaidParser.NodeShape.Rhombus, "{"},
        { MermaidParser.NodeShape.Circle, "(("},
        { MermaidParser.NodeShape.Subroutine, "[["},
        { MermaidParser.NodeShape.RoundRect, "("},
    };

    // 获取形状的闭合符号
    private static string GetShapeClosing(string shapeOpening)
    {
        return shapeOpening switch
        {
            "((" => "))", // 圆形闭合
            "{" => "}",   // 菱形闭合
            "([" => "])", // 体育场形状闭合
            "[[" => "]]", // 子图
            "[(" => ")]", // 圆柱形闭合
            "(" => ")", // 圆角矩形闭合
            _ => "]"      // 默认矩形闭合
        };
    }

    // 获取节点位置
    private static Vector2 GetNodePosition(Node node)
    {
        Rect position = node.GetPosition();
        return new Vector2(position.x, position.y);
    }

    // 保存到文件的辅助方法
    public static void SaveToFile(GraphView graphView, string filePath, string title = "Graph")
    {
        string mermaidContent = ConvertToMermaid(graphView, title);

        try
        {
            System.IO.File.WriteAllText(filePath, mermaidContent);
            Debug.Log($"Mermaid图已保存到: {filePath}");
        }
        catch (System.Exception e)
        {
            Debug.LogError($"保存文件失败: {e.Message}");
        }
    }


    public static void ApplyPositionsFromMermaid(GraphView graphView, string mermaidContent)
    {
        var nodes = graphView.nodes.ToList().Cast<Node>().ToList();
        var positionMap = ParsePositionDefinitions(mermaidContent);

        foreach (var entry in positionMap)
        {
            string nodeId = entry.Key;
            Vector2 position = entry.Value;

            // 查找对应的节点
            Node targetNode = nodes.FirstOrDefault((node) => {
                var mermaidNode = node.userData as MermaidNode;
                return mermaidNode.mermaidId == nodeId && node.viewDataKey == mermaidNode.GUID;
            });

            targetNode?.SetPosition(new Rect(position, Vector2.zero));
        }
    }

    public static Dictionary<string, Vector2> ParsePositionDefinitions(string mermaidContent)
    {
        var positionMap = new Dictionary<string, Vector2>();
        var lines = mermaidContent.Split('\n');

        bool inPositionBlock = false;

        foreach (string line in lines)
        {
            string trimmedLine = line.Trim();

            if (trimmedLine.StartsWith("%% PosDef:begin"))
            {
                inPositionBlock = true;
                continue;
            }

            if (trimmedLine.StartsWith("%% PosDef:end"))
            {
                inPositionBlock = false;
                continue;
            }

            if (inPositionBlock && trimmedLine.StartsWith("%%"))
            {
                // 解析格式: %%  A:pos:300,100
                string content = trimmedLine.Substring(2).Trim(); // 移除 %%
                string[] parts = content.Split(':');

                if (parts.Length >= 3 && parts[1].Trim() == "pos")
                {
                    string nodeId = parts[0].Trim();
                    string[] coords = parts[2].Split(',');

                    if (coords.Length == 2 &&
                        float.TryParse(coords[0], out float x) &&
                        float.TryParse(coords[1], out float y))
                    {
                        positionMap[nodeId] = new Vector2(x, y);
                    }
                }
            }
        }

        return positionMap;
    }

    
}